/*
 * Copyright 2006 Kevin Wetzels 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0 
 *       
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License.
 */
package be.roam.drest.service.youtube;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import org.apache.commons.httpclient.methods.GetMethod;
import org.xml.sax.SAXException;

import be.roam.drest.service.common.HttpRestService;
import be.roam.drest.service.youtube.xml.YouTubeXmlParser;
import be.roam.util.CollectionsUtil;

public class YouTubeService extends HttpRestService {
    
    private static final String YOU_TUBE_URL = "http://www.youtube.com/api2_rest?method=youtube.";
    
    private String developerId;
    
    public YouTubeService(String developerId) {
        super();
        this.developerId = developerId;
    }
    
    public InputStream getUserProfileRaw(String userName) throws IOException {
        GetMethod method = createGetMethod(YOU_TUBE_URL + "users.get_profile&dev_id=" + developerId + "&user=" + userName);
        client.executeMethod(method);
        return method.getResponseBodyAsStream();
    }
    
    public YouTubeUserProfile getUserProfile(String userName) throws IOException, SAXException {
        InputStream inputStream = getUserProfileRaw(userName);
        if (inputStream == null) {
            return null;
        }
        YouTubeUserProfile userProfile = YouTubeXmlParser.parseUserProfile(inputStream);
        inputStream.close();
        if (userProfile != null) {
            userProfile.setUserName(userName);
        }
        return userProfile;
    }
    
    public InputStream getFavoriteVideosRaw(String userName) throws IOException {
        GetMethod method = createGetMethod(YOU_TUBE_URL + "users.list_favorite_videos&dev_id=" + developerId + "&user=" + userName);
        client.executeMethod(method);
        return method.getResponseBodyAsStream();
    }
    
    public List<YouTubeVideo> getFavoriteVideos(String userName) throws IOException, SAXException {
        InputStream inputStream = getFavoriteVideosRaw(userName);
        if (inputStream == null) {
            return null;
        }
        List<YouTubeVideo> list = YouTubeXmlParser.parseVideoList(inputStream);
        inputStream.close();
        return list;
    }
    
    public InputStream getFriendListRaw(String userName) throws IOException {
        GetMethod method = createGetMethod(YOU_TUBE_URL + "users.list_friends&dev_id=" + developerId + "&user=" + userName);
        client.executeMethod(method);
        return method.getResponseBodyAsStream();
    }
    
    /**
     * Retrieves the list of friends for the given user.
     * <p>
     * The response of YouTube is limited to the user name, number of uploaded videos, number
     * of favorite videos and the number of friends.
     * </p>
     * 
     * @param userName name of the user
     * 
     * @return list of user profiles for the friends
     * 
     * @throws IOException
     * @throws SAXException
     */
    public List<YouTubeUserProfile> getFriendList(String userName) throws IOException, SAXException {
        InputStream inputStream = getFriendListRaw(userName);
        if (inputStream == null) {
            return null;
        }
        List<YouTubeUserProfile> list = YouTubeXmlParser.parseFriendList(inputStream);
        inputStream.close();
        return list;
    }
    
    public InputStream getVideoDetailsRaw(String videoId) throws IOException {
        GetMethod method = createGetMethod(YOU_TUBE_URL + "videos.get_details&dev_id=" + developerId + "&video_id=" + videoId);
        client.executeMethod(method);
        return method.getResponseBodyAsStream();
    }
    
    public YouTubeVideo getVideoDetails(String videoId) throws IOException, SAXException {
        InputStream inputStream = getVideoDetailsRaw(videoId);
        if (inputStream == null) {
            return null;
        }
        List<YouTubeVideo> list = YouTubeXmlParser.parseVideoList(inputStream);
        inputStream.close();
        if (CollectionsUtil.isNullOrEmpty(list)) {
            return null;
        }
        YouTubeVideo tubeVideo = list.get(0);
        // youtube doesn't put the video id in the XML... but we want it in there for consistancy.
        tubeVideo.setId(videoId);
        return tubeVideo;
    }
    
    public InputStream getVideoListByTagRaw(String tag, Integer pageNr, Integer resultsPerPage) throws IOException {
        String url = YOU_TUBE_URL + "videos.list_by_tag&dev_id=" + developerId + "&tag=" + tag;
        if (pageNr != null) {
            url += "&page=" + pageNr;
        }
        if (resultsPerPage != null) {
            url += "&per_page=" + resultsPerPage;
        }
        GetMethod method = createGetMethod(url);
        client.executeMethod(method);
        return method.getResponseBodyAsStream();
    }
    
    public List<YouTubeVideo> getVideoListByTag(String tag, Integer pageNr, Integer resultsPerPage) throws IOException, SAXException {
        InputStream inputStream = getVideoListByTagRaw(tag, pageNr, resultsPerPage);
        if (inputStream == null) {
            return null;
        }
        List<YouTubeVideo> list = YouTubeXmlParser.parseVideoList(inputStream);
        inputStream.close();
        return list;
    }
    
    public InputStream getVideosByUserRaw(String userName) throws IOException {
        GetMethod method = createGetMethod(YOU_TUBE_URL + "videos.list_by_user&dev_id=" + developerId + "&user=" + userName);
        client.executeMethod(method);
        return method.getResponseBodyAsStream();
    }

    public List<YouTubeVideo> getVideosByUser(String userName) throws IOException, SAXException {
        InputStream inputStream = getVideosByUserRaw(userName);
        if (inputStream == null) {
            return null;
        }
        List<YouTubeVideo> list = YouTubeXmlParser.parseVideoList(inputStream);
        inputStream.close();
        return list;
    }
    
    public InputStream getFeaturedVideosRaw() throws IOException {
        GetMethod method = createGetMethod(YOU_TUBE_URL + "videos.list_featured&dev_id=" + developerId);
        client.executeMethod(method);
        return method.getResponseBodyAsStream();
    }

    public List<YouTubeVideo> getFeaturedVideos() throws IOException, SAXException {
        InputStream inputStream = getFeaturedVideosRaw();
        if (inputStream == null) {
            return null;
        }
        List<YouTubeVideo> list = YouTubeXmlParser.parseVideoList(inputStream);
        inputStream.close();
        return list;
    }

}
